import traceback

import pymysql
from pymysql.cursors import DictCursor

from infra import logging_handler
from infra.config_holder import conf

host = conf['mysql']['host']
port = conf['mysql']['port']
user = conf['mysql']['user']
password = conf['mysql']['password']
db = conf['mysql']['db']
autocommit = True

logger = logging_handler.get_app_log()


def get_conn():
    try:
        conn = pymysql.connect(
            host=host,
            port=port,
            user=user,
            password=password,
            db=db,
            autocommit=autocommit
        )
    except Exception as e:
        logger.error(f"get connection from db={host}:{port} failed.")
        logger.error(traceback.format_exc())
        raise e

    return conn


def get_cursor(conn, cursor_type=pymysql.cursors.DictCursor):
    try:
        cursor = conn.cursor(cursor_type)
    except Exception as e:
        logger.error(f"get cursor from db={host}:{port} failed.")
        logger.error(traceback.format_exc())
        raise e

    return cursor


def execute(sql: str, param: list):
    conn = get_conn()
    cursor = get_cursor(conn)
    try:
        cursor.execute(sql, param)
        result = cursor.fetchall()
    except Exception as e:
        logger.error(f"exec [sql={str}, param={param}] failed.")
        logger.error(traceback.format_exc())
        conn.rollback()
        raise e
    finally:
        cursor.close()
        conn.close()

    return result


def batch_execute(sql: str, param: list):
    conn = get_conn()
    cursor = get_cursor(conn)
    try:
        # 返回值设置为字典，方便处理
        cursor.executemany(sql, param)
        result = cursor.fetchall()
    except Exception as e:
        logger.error(f"batch exec [sql={str}, param={param}] failed.")
        logger.error(traceback.format_exc())
        conn.rollback()
        raise e
    finally:
        cursor.close()
        conn.close()

    return result
